import json
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from django.core.exceptions import ValidationError
from django.db import transaction
from django.contrib.auth.decorators import login_required

from rbac.models import Role, Permission, RolePermission, RbacUser, UserRole, PermissionManager
from rbac.auto_permissions import auto_permission_generator


@login_required
def role_list(request):
    """角色列表页面"""
    # 检查权限
    if not request.current_user or not has_permission(request.current_user['id'], 'role.list'):
        messages.error(request, '您没有权限访问此页面')
        return redirect('/rbac/')
    
    roles = Role.objects.all().order_by('name')
    permissions = Permission.objects.all().order_by('group', 'name')
    
    # 按组织织权限
    permission_groups = {}
    for perm in permissions:
        if perm.group not in permission_groups:
            permission_groups[perm.group] = []
        permission_groups[perm.group].append(perm)
    
    context = {
        'roles': roles,
        'permissions': permissions,
        'permission_groups': permission_groups,
        'current_user': request.current_user
    }
    return render(request, 'rbac/role_management.html', context)


@csrf_exempt
@require_http_methods(["POST"])
def role_add(request):
    """添加角色"""
    if not has_permission(request.current_user['id'], 'role.add'):
        return JsonResponse({'success': False, 'message': '没有权限'})
    
    try:
        data = json.loads(request.body)
        role_name = data.get('name', '').strip()
        role_code = data.get('code', '').strip()
        description = data.get('description', '').strip()
        
        if not role_name or not role_code:
            return JsonResponse({'success': False, 'message': '角色名称和代码不能为空'})
        
        # 检查重复
        if Role.objects.filter(name=role_name).exists():
            return JsonResponse({'success': False, 'message': '角色名称已存在'})
        if Role.objects.filter(code=role_code).exists():
            return JsonResponse({'success': False, 'message': '角色代码已存在'})
        
        role = Role.objects.create(
            name=role_name,
            code=role_code,
            description=description,
            is_system=False
        )
        
        return JsonResponse({
            'success': True, 
            'message': '角色创建成功',
            'role': {
                'id': role.id,
                'name': role.name,
                'code': role.code,
                'description': role.description
            }
        })
        
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'创建失败: {str(e)}'})


@csrf_exempt
@require_http_methods(["POST"])
def role_edit(request, role_id):
    """编辑角色"""
    if not has_permission(request.current_user['id'], 'role.edit'):
        return JsonResponse({'success': False, 'message': '没有权限'})
    
    try:
        role = get_object_or_404(Role, id=role_id)
        
        data = json.loads(request.body)
        role_name = data.get('name', '').strip()
        role_code = data.get('code', '').strip()
        description = data.get('description', '').strip()
        
        if not role_name or not role_code:
            return JsonResponse({'success': False, 'message': '角色名称和代码不能为空'})
        
        # 检查重复（排除当前角色）
        if Role.objects.filter(name=role_name).exclude(id=role_id).exists():
            return JsonResponse({'success': False, 'message': '角色名称已存在'})
        if Role.objects.filter(code=role_code).exclude(id=role_id).exists():
            return JsonResponse({'success': False, 'message': '角色代码已存在'})
        
        # 系统角色的特殊日志记录
        if role.is_system:
            import logging
            logger = logging.getLogger('rbac')
            user_info = request.current_user.get('username', 'unknown')
            logger.warning(f'系统角色编辑: 用户 {user_info} 编辑了系统角色 {role.name} (ID: {role.id})')
        
        role.name = role_name
        role.code = role_code
        role.description = description
        role.save()
        
        message = '角色更新成功'
        if role.is_system:
            message += '（系统角色已更新，请注意系统稳定性）'
        
        return JsonResponse({'success': True, 'message': message})
        
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'更新失败: {str(e)}'})


@csrf_exempt
@require_http_methods(["POST"])
def role_delete(request, role_id):
    """删除角色"""
    if not has_permission(request.current_user['id'], 'role.delete'):
        return JsonResponse({'success': False, 'message': '没有权限'})
    
    try:
        role = get_object_or_404(Role, id=role_id)
        
        # 系统角色的特殊日志记录和警告
        if role.is_system:
            import logging
            logger = logging.getLogger('rbac')
            user_info = request.current_user.get('username', 'unknown')
            logger.warning(f'危险操作: 用户 {user_info} 删除了系统角色 {role.name} (ID: {role.id})')
            
            # 系统角色删除的额外检查
            critical_roles = ['super_admin', 'admin']  # 关键系统角色
            if role.code in critical_roles:
                # 关键系统角色的额外保护检查
                remaining_admins = Role.objects.filter(
                    code__in=critical_roles, 
                    is_active=True
                ).exclude(id=role.id).count()
                
                if remaining_admins == 0:
                    return JsonResponse({
                        'success': False, 
                        'message': f'不能删除最后一个{role.name}角色，这将导致系统无法管理！'
                    })
        
        # 检查是否有用户在使用此角色
        if UserRole.objects.filter(role=role).exists():
            return JsonResponse({'success': False, 'message': '该角色正在被用户使用，不能删除'})
        
        role_name = role.name
        role_type = '系统角色' if role.is_system else '自定义角色'
        role.delete()
        
        message = f'{role_type}“{role_name}”已删除'
        if role.is_system:
            message += '（警告：已删除系统角色，请检查系统功能）'
        
        return JsonResponse({'success': True, 'message': message})
        
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'删除失败: {str(e)}'})


@csrf_exempt
@require_http_methods(["POST"])
def role_toggle_status(request, role_id):
    """切换角色状态"""
    if not has_permission(request.current_user['id'], 'role.edit'):
        return JsonResponse({'success': False, 'message': '没有权限'})
    
    try:
        role = get_object_or_404(Role, id=role_id)
        role.is_active = not role.is_active
        role.save()
        
        status_text = '启用' if role.is_active else '禁用'
        return JsonResponse({'success': True, 'message': f'角色已{status_text}'})
        
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'操作失败: {str(e)}'})


@csrf_exempt
@require_http_methods(["POST"])
def role_manage_permissions(request, role_id):
    """管理角色权限"""
    if not has_permission(request.current_user['id'], 'role.manage_permissions'):
        return JsonResponse({'success': False, 'message': '没有权限'})
    
    try:
        role = get_object_or_404(Role, id=role_id)
        data = json.loads(request.body)
        permission_ids = data.get('permission_ids', [])
        
        with transaction.atomic():
            # 清除现有权限
            RolePermission.objects.filter(role=role).delete()
            
            # 添加新权限
            current_user = RbacUser.objects.get(id=request.current_user['id'])
            for perm_id in permission_ids:
                permission = Permission.objects.get(id=perm_id)
                RolePermission.objects.create(
                    role=role,
                    permission=permission,
                    granted_by=current_user
                )
        
        return JsonResponse({'success': True, 'message': '权限分配成功'})
        
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'权限分配失败: {str(e)}'})


def get_role_permissions(request, role_id):
    """获取角色的权限列表"""
    try:
        role = get_object_or_404(Role, id=role_id)
        permission_ids = list(role.permissions.values_list('id', flat=True))
        for per in permission_ids:
            print(Permission.objects.get(id=per))
        
        return JsonResponse({'success': True, 'permission_ids': permission_ids})
    except Exception as e:
        return JsonResponse({'success': False, 'message': str(e)})


@csrf_exempt
@require_http_methods(["POST"])
def sync_all_permissions(request):
    """同步所有应用的权限并创建基础角色"""
    # 检查是否为超级用户或有相应权限
    if not request.current_user:
        return JsonResponse({'success': False, 'message': '用户未登录'})
    
    user_id = request.current_user['id']
    is_superuser = request.current_user.get('is_superuser', False)
    
    if not (is_superuser or has_permission(user_id, 'role.manage_permissions')):
        return JsonResponse({'success': False, 'message': '只有超级管理员或有权限的用户可以执行此操作'})
    
    try:
        from rbac.auto_permissions import AutoPermissionGenerator
        from rbac.models import PermissionManager
        import json
        
        # 检查是否需要清理孤立权限
        request_data = {}
        if request.content_type == 'application/json' and request.body:
            try:
                request_data = json.loads(request.body)
            except json.JSONDecodeError:
                pass
        
        clean_orphaned = request_data.get('clean_orphaned', True)  # 默认清理孤立权限
        
        # 1. 初始化基础角色（如果不存在）
        PermissionManager.init_roles()
        
        # 2. 自动生成所有应用的权限（包括清理孤立权限）
        auto_permission_generator = AutoPermissionGenerator()
        result = auto_permission_generator.auto_create_permissions(scan_all_apps=True, clean_orphaned=clean_orphaned)
        
        # 3. 为新创建的权限分配给默认角色
        if result['created']:
            auto_permission_generator.assign_permissions_to_default_roles(result['created'])
        
        # 构建成功消息
        message_parts = []
        if result['created']:
            message_parts.append(f"新创建 {len(result['created'])} 个权限")
        if result['updated']:
            message_parts.append(f"更新 {len(result['updated'])} 个权限")
        if result.get('deleted_count', 0) > 0:
            message_parts.append(f"清理 {result['deleted_count']} 个孤立权限")
        
        if not message_parts:
            message = "权限同步完成，没有变更"
        else:
            message = f"权限同步成功！{'，'.join(message_parts)}，基础角色已就绪"
        
        return JsonResponse({
            'success': True, 
            'message': message,
            'data': {
                'created_count': len(result['created']),
                'updated_count': len(result['updated']),
                'deleted_count': result.get('deleted_count', 0),
                'total_discovered': result['total_discovered']
            }
        })
    except Exception as e:
        import traceback
        traceback.print_exc()
        return JsonResponse({'success': False, 'message': f'权限同步失败: {str(e)}'})





def has_permission(user_id, permission_code):
    """检查用户是否具有指定权限"""
    if not user_id:
        return False
    
    try:
        user = RbacUser.objects.get(id=user_id)
        # 超级用户拥有所有权限
        if user.is_superuser:
            return True
        return user.has_permission(permission_code)
    except RbacUser.DoesNotExist:
        return False


@login_required
def permission_list(request):
    """权限列表页面"""
    # 检查是否为超级用户或有相应权限
    user_id = request.current_user['id']
    is_superuser = request.current_user.get('is_superuser', False)
    
    if not (is_superuser or has_permission(user_id, 'role.list')):
        messages.error(request, '您没有权限访问此页面')
        return redirect('/rbac/')
    
    
    permissions = Permission.objects.all().order_by('group', 'name')
    
    
    # 按应用和分组组织权限
    app_groups = {}
    for perm in permissions:
        # 从权限代码中提取应用名
        app_name = perm.code.split('.')[0] if '.' in perm.code else 'system'
        app_display_name = {
            'rbac': 'RBAC权限系统',
            'pm': 'PM项目管理',
            'system': '系统管理',
            'user': '用户管理',
            'role': '角色管理'
        }.get(app_name, app_name.upper())
        
        if app_display_name not in app_groups:
            app_groups[app_display_name] = {
                'app_code': app_name,
                'groups': {},
                'total_count': 0
            }
        
        # 在应用内按分组组织
        group_name = perm.group
        if group_name not in app_groups[app_display_name]['groups']:
            app_groups[app_display_name]['groups'][group_name] = []
        
        app_groups[app_display_name]['groups'][group_name].append(perm)
        app_groups[app_display_name]['total_count'] += 1
    
    # 计算统计信息
    total_permissions = permissions.count()
    total_groups = sum(len(app['groups']) for app in app_groups.values())
    total_apps = len(app_groups)
    
    context = {
        'permissions': permissions,
        'app_groups': app_groups,
        'current_user': request.current_user,
        'stats': {
            'total_permissions': total_permissions,
            'total_groups': total_groups,
            'total_apps': total_apps
        }
    }
    
    return render(request, 'rbac/permission_list.html', context)


@csrf_exempt
@require_http_methods(["POST"])
def clean_orphaned_permissions(request):
    """清理孤立权限（对应视图函数已不存在的权限）"""
    # 检查是否为超级用户或有相应权限
    if not request.current_user:
        return JsonResponse({'success': False, 'message': '用户未登录'})
    
    user_id = request.current_user['id']
    is_superuser = request.current_user.get('is_superuser', False)
    
    if not (is_superuser or has_permission(user_id, 'role.manage_permissions')):
        return JsonResponse({'success': False, 'message': '只有超级管理员或有权限的用户可以执行此操作'})
    
    try:
        from rbac.auto_permissions import AutoPermissionGenerator
        
        auto_permission_generator = AutoPermissionGenerator()
        result = auto_permission_generator.clean_orphaned_permissions()
        
        if result['count'] > 0:
            message = f"清理完成！删除了 {result['count']} 个孤立权限"
        else:
            message = "没有发现孤立权限，数据库已经是最新的"
        
        return JsonResponse({
            'success': True,
            'message': message,
            'data': {
                'deleted_count': result['count'],
                'deleted_permissions': result['deleted']
            }
        })
    except Exception as e:
        import traceback
        traceback.print_exc()
        return JsonResponse({'success': False, 'message': f'清理失败: {str(e)}'})